home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / share / gtk-2.0 / demo / iconview.c < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-25  |  8.4 KB  |  360 lines

  1. /* Icon View/Icon View Basics
  2.  *
  3.  * The GtkIconView widget is used to display and manipulate icons.  
  4.  * It uses a GtkTreeModel for data storage, so the list store 
  5.  * example might be helpful.
  6.  */
  7.  
  8. #include <gtk/gtk.h>
  9. #include <string.h>
  10. #include "demo-common.h"
  11.  
  12. static GtkWidget *window = NULL;
  13.  
  14. #define FOLDER_NAME "gnome-fs-directory.png"
  15. #define FILE_NAME "gnome-fs-regular.png"
  16.  
  17. enum
  18. {
  19.   COL_PATH,
  20.   COL_DISPLAY_NAME,
  21.   COL_PIXBUF,
  22.   COL_IS_DIRECTORY,
  23.   NUM_COLS
  24. };
  25.  
  26.  
  27. static GdkPixbuf *file_pixbuf, *folder_pixbuf;
  28. gchar *parent;
  29. GtkToolItem *up_button;
  30.  
  31. /* Loads the images for the demo and returns whether the operation succeeded */
  32. static gboolean
  33. load_pixbufs (GError **error)
  34. {
  35.   char *filename;
  36.  
  37.   if (file_pixbuf)
  38.     return TRUE; /* already loaded earlier */
  39.  
  40.   /* demo_find_file() looks in the the current directory first,
  41.    * so you can run gtk-demo without installing GTK, then looks
  42.    * in the location where the file is installed.
  43.    */
  44.   filename = demo_find_file (FILE_NAME, error);
  45.   if (!filename)
  46.     return FALSE; /* note that "error" was filled in and returned */
  47.  
  48.   file_pixbuf = gdk_pixbuf_new_from_file (filename, error);
  49.   g_free (filename);
  50.   
  51.   if (!file_pixbuf)
  52.     return FALSE; /* Note that "error" was filled with a GError */
  53.   
  54.   filename = demo_find_file (FOLDER_NAME, error);
  55.   if (!filename)
  56.     return FALSE; /* note that "error" was filled in and returned */
  57.  
  58.   folder_pixbuf = gdk_pixbuf_new_from_file (filename, error);
  59.   g_free (filename);
  60.  
  61.   return TRUE;
  62. }
  63.  
  64. static void
  65. fill_store (GtkListStore *store)
  66. {
  67.   GDir *dir;
  68.   const gchar *name;
  69.   GtkTreeIter iter;
  70.   
  71.   /* First clear the store */
  72.   gtk_list_store_clear (store);
  73.  
  74.   /* Now go through the directory and extract all the file
  75.    * information */
  76.   dir = g_dir_open (parent, 0, NULL);
  77.   if (!dir)
  78.     return;
  79.  
  80.   name = g_dir_read_name (dir);
  81.   while (name != NULL)
  82.     {
  83.       gchar *path, *display_name;
  84.       gboolean is_dir;
  85.       
  86.       /* We ignore hidden files that start with a '.' */
  87.       if (name[0] != '.')
  88.     {
  89.       path = g_build_filename (parent, name, NULL);
  90.  
  91.       is_dir = g_file_test (path, G_FILE_TEST_IS_DIR);
  92.       
  93.       display_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
  94.  
  95.       gtk_list_store_append (store, &iter);
  96.       gtk_list_store_set (store, &iter,
  97.                   COL_PATH, path,
  98.                   COL_DISPLAY_NAME, display_name,
  99.                   COL_IS_DIRECTORY, is_dir,
  100.                   COL_PIXBUF, is_dir ? folder_pixbuf : file_pixbuf,
  101.                   -1);
  102.       g_free (path);
  103.       g_free (display_name);
  104.     }
  105.  
  106.       name = g_dir_read_name (dir);      
  107.     }
  108. }
  109.  
  110. static gint
  111. sort_func (GtkTreeModel *model,
  112.        GtkTreeIter  *a,
  113.        GtkTreeIter  *b,
  114.        gpointer      user_data)
  115. {
  116.   gboolean is_dir_a, is_dir_b;
  117.   gchar *name_a, *name_b;
  118.   int ret;
  119.  
  120.   /* We need this function because we want to sort
  121.    * folders before files.
  122.    */
  123.  
  124.   
  125.   gtk_tree_model_get (model, a,
  126.               COL_IS_DIRECTORY, &is_dir_a,
  127.               COL_DISPLAY_NAME, &name_a,
  128.               -1);
  129.  
  130.   gtk_tree_model_get (model, b,
  131.               COL_IS_DIRECTORY, &is_dir_b,
  132.               COL_DISPLAY_NAME, &name_b,
  133.               -1);
  134.  
  135.   if (!is_dir_a && is_dir_b)
  136.     ret = 1;
  137.   else if (is_dir_a && !is_dir_b)
  138.     ret = -1;
  139.   else
  140.     {
  141.       ret = g_utf8_collate (name_a, name_b);
  142.     }
  143.  
  144.   g_free (name_a);
  145.   g_free (name_b);
  146.  
  147.   return ret;
  148. }
  149.  
  150. static GtkListStore *
  151. create_store (void)
  152. {
  153.   GtkListStore *store;
  154.  
  155.   store = gtk_list_store_new (NUM_COLS,
  156.                   G_TYPE_STRING, 
  157.                   G_TYPE_STRING, 
  158.                   GDK_TYPE_PIXBUF,
  159.                   G_TYPE_BOOLEAN);
  160.  
  161.   /* Set sort column and function */ 
  162.   gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (store),
  163.                        sort_func,
  164.                        NULL, NULL);
  165.   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
  166.                     GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
  167.                     GTK_SORT_ASCENDING);
  168.  
  169.   return store;
  170. }
  171.  
  172. static void
  173. item_activated (GtkIconView *icon_view,
  174.         GtkTreePath *tree_path,
  175.         gpointer     user_data)
  176. {
  177.   GtkListStore *store;
  178.   gchar *path;
  179.   GtkTreeIter iter;
  180.   gboolean is_dir;
  181.   
  182.   store = GTK_LIST_STORE (user_data);
  183.  
  184.   gtk_tree_model_get_iter (GTK_TREE_MODEL (store),
  185.                &iter, tree_path);
  186.   gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
  187.               COL_PATH, &path,
  188.               COL_IS_DIRECTORY, &is_dir,
  189.               -1);
  190.  
  191.   if (!is_dir)
  192.     {
  193.       g_free (path);
  194.       return;
  195.     }
  196.   
  197.   /* Replace parent with path and re-fill the model*/
  198.   g_free (parent);
  199.   parent = path;
  200.  
  201.   fill_store (store);
  202.  
  203.   /* Sensitize the up button */
  204.   gtk_widget_set_sensitive (GTK_WIDGET (up_button), TRUE);
  205. }
  206.  
  207. static void
  208. up_clicked (GtkToolItem *item,
  209.         gpointer     user_data)
  210. {
  211.   GtkListStore *store;
  212.   gchar *dir_name;
  213.  
  214.   store = GTK_LIST_STORE (user_data);
  215.  
  216.   dir_name = g_path_get_dirname (parent);
  217.   g_free (parent);
  218.   
  219.   parent = dir_name;
  220.  
  221.   fill_store (store);
  222.  
  223.   /* Maybe de-sensitize the up button */
  224.   gtk_widget_set_sensitive (GTK_WIDGET (up_button),
  225.                 strcmp (parent, "/") != 0);
  226. }
  227.  
  228. static void
  229. home_clicked (GtkToolItem *item,
  230.           gpointer     user_data)
  231. {
  232.   GtkListStore *store;
  233.  
  234.   store = GTK_LIST_STORE (user_data);
  235.  
  236.   g_free (parent);
  237.   parent = g_strdup (g_get_home_dir ());
  238.  
  239.   fill_store (store);
  240.  
  241.   /* Sensitize the up button */
  242.   gtk_widget_set_sensitive (GTK_WIDGET (up_button),
  243.                 TRUE);
  244. }
  245.  
  246. GtkWidget *
  247. do_iconview (GtkWidget *do_widget)
  248. {
  249.   if (!window)
  250.     {
  251.       GError *error;
  252.             
  253.       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  254.       gtk_window_set_default_size (GTK_WINDOW (window), 650, 400);
  255.       
  256.       gtk_window_set_screen (GTK_WINDOW (window),
  257.                  gtk_widget_get_screen (do_widget));
  258.       gtk_window_set_title (GTK_WINDOW (window), "GtkIconView demo");
  259.  
  260.       g_signal_connect (window, "destroy",
  261.             G_CALLBACK (gtk_widget_destroyed), &window);
  262.  
  263.       error = NULL;
  264.       if (!load_pixbufs (&error))
  265.     {
  266.       GtkWidget *dialog;
  267.  
  268.       dialog = gtk_message_dialog_new (GTK_WINDOW (window),
  269.                        GTK_DIALOG_DESTROY_WITH_PARENT,
  270.                        GTK_MESSAGE_ERROR,
  271.                        GTK_BUTTONS_CLOSE,
  272.                        "Failed to load an image: %s",
  273.                        error->message);
  274.  
  275.       g_error_free (error);
  276.  
  277.       g_signal_connect (dialog, "response",
  278.                 G_CALLBACK (gtk_widget_destroy), NULL);
  279.  
  280.       gtk_widget_show (dialog);
  281.     }
  282.       else
  283.     {
  284.       GtkWidget *sw;
  285.       GtkWidget *icon_view;
  286.       GtkListStore *store;
  287.       GtkWidget *vbox;
  288.       GtkWidget *tool_bar;
  289.       GtkToolItem *home_button;
  290.       
  291.       vbox = gtk_vbox_new (FALSE, 0);
  292.       gtk_container_add (GTK_CONTAINER (window), vbox);
  293.  
  294.       tool_bar = gtk_toolbar_new ();
  295.       gtk_box_pack_start (GTK_BOX (vbox), tool_bar, FALSE, FALSE, 0);
  296.       
  297.       up_button = gtk_tool_button_new_from_stock (GTK_STOCK_GO_UP);
  298.       gtk_tool_item_set_is_important (up_button, TRUE);
  299.       gtk_widget_set_sensitive (GTK_WIDGET (up_button), FALSE);
  300.       gtk_toolbar_insert (GTK_TOOLBAR (tool_bar), up_button, -1);
  301.  
  302.       home_button = gtk_tool_button_new_from_stock (GTK_STOCK_HOME);
  303.       gtk_tool_item_set_is_important (home_button, TRUE);
  304.       gtk_toolbar_insert (GTK_TOOLBAR (tool_bar), home_button, -1);
  305.       
  306.       
  307.       sw = gtk_scrolled_window_new (NULL, NULL);
  308.       gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
  309.                            GTK_SHADOW_ETCHED_IN);
  310.       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
  311.                       GTK_POLICY_AUTOMATIC,
  312.                       GTK_POLICY_AUTOMATIC);
  313.       
  314.       gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
  315.       
  316.       /* Create the store and fill it with the contents of '/' */
  317.       parent = g_strdup ("/");
  318.       store = create_store ();
  319.       fill_store (store);
  320.  
  321.       icon_view = gtk_icon_view_new_with_model (GTK_TREE_MODEL (store));
  322.       gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (icon_view),
  323.                         GTK_SELECTION_MULTIPLE);
  324.       g_object_unref (store);
  325.       
  326.       /* Connect to the "clicked" signal of the "Up" tool button */
  327.       g_signal_connect (up_button, "clicked",
  328.                 G_CALLBACK (up_clicked), store);
  329.  
  330.       /* Connect to the "clicked" signal of the "Home" tool button */
  331.       g_signal_connect (home_button, "clicked",
  332.                 G_CALLBACK (home_clicked), store);
  333.       
  334.       /* We now set which model columns that correspond to the text
  335.        * and pixbuf of each item
  336.        */
  337.       gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), COL_DISPLAY_NAME);
  338.       gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), COL_PIXBUF);
  339.  
  340.       /* Connect to the "item_activated" signal */
  341.       g_signal_connect (icon_view, "item_activated",
  342.                 G_CALLBACK (item_activated), store);
  343.       gtk_container_add (GTK_CONTAINER (sw), icon_view);
  344.  
  345.       gtk_widget_grab_focus (icon_view);
  346.     }
  347.     }
  348.   
  349.   if (!GTK_WIDGET_VISIBLE (window))
  350.     gtk_widget_show_all (window);
  351.   else
  352.     {
  353.       gtk_widget_destroy (window);
  354.       window = NULL;
  355.     }
  356.  
  357.   return window;
  358. }
  359.  
  360.